﻿using Engine;
using Game;
using Game.NetWork;
using Game.NetWork.Packages;
using Game.Server;
using Game.Server.Event;
using Game.Server.PlayerEvent;
using GameEntitySystem;
using MessagePack;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using XmlUtilities;
using System.Xml.Linq;
using System.Xml;
using System.Web;
using MessagePack.Formatters;

namespace Game.Server.Plugins
{
    public class eatthing : ServerPlugin, IPlayerInventoryHandle
    {
        public override int Version => 100;

        public class EatThingInfo
        {
            public float[,] 事件序号及恢复系数 = new float[,] { { 1, 5 } };
        }

        public static readonly string Path = $@"PluginData/eatthing.json";

        public Dictionary<int, EatThingInfo> ff = new Dictionary<int, EatThingInfo>();

        public Dictionary<int, EatThingInfo> 内存字典 = new Dictionary<int, EatThingInfo>();

        public 方法集合 方法集合 = new 方法集合();

        public override string Name => "json吃东西插件";

        public byte FirstLevel => 1; // 第一级(1-255)

        public override void Initialize() //初始化
        {
            //事件注册
            PlayerInventoryEventManager.AddObject(this);

            if (!File.Exists(Path))
            {
                ff = new Dictionary<int, EatThingInfo>()
                {
                    {2,new EatThingInfo{事件序号及恢复系数 = new float[,]{ { 0,0.5f },{2,0} } } },
                    {3,new EatThingInfo{事件序号及恢复系数 = new float[,]{ { 2,0 } } } }
                };
                //创建json文件
                File.Create(Path).Close();
                File.WriteAllText(Path, JsonConvert.SerializeObject(ff));// 写入json文件
                Log.Information("文件创建成功");
            }
            else
            {
                Log.Information("已创建");
            }
        }

        public void 加载json文件()
        {
            try
            {
                string path1 = File.ReadAllText(Path);
                内存字典 = JsonConvert.DeserializeObject<Dictionary<int, EatThingInfo>>(path1);
                Log.Information("加载json文件成功");
            }
            catch (Exception e)
            {
                Log.Error("加载json文件失败" + e.Message);
            }
        }


        public override void Load()
        {
            加载json文件();
            Log.Information("路径:PluginData/eatthing.json  json文件配置过程\n :\"3\":{事件序号及恢复系数\":[[2.0,0.0]]}\n" +
                $"引号里的3代表方块id\n时间序号介绍" +
                $"0:回血\n1:感冒\n2:治愈感冒 恢复系数随机填\n3:摔落抗性系数增量\n4:提高攻击抗性\n" +
                $"2.0代表事件序号 0.0代表恢复系数  [[2.0,0.0]]代表事件序号及恢复系数\n" +
                $"支持一个方块id添加多个方块吃东西事件");

            foreach (var data in 内存字典)
            {
                BlocksManager.Blocks[data.Key].FoodType = FoodType.Fruit;
                BlocksManager.Blocks[data.Key].DefaultNutritionalValue = 0.00001f;
            }

        }

        public override void Save()
        {

        }

        public bool PlayerDrop(ComponentPlayer componentPlayer)
        {
            return true;
        }

        public bool PlayerDrapDrop(ComponentPlayer componentPlayer, Vector3 worldPos, InventoryDragData inventoryDragData, int count)
        {
            return true;
        }

        public bool PlayerHandleMoveItem(ComponentPlayer componentPlayer, IInventory sourceInventory, int sourceSlotIndex, IInventory targetInventory, int targetSlotIndex, int count)
        {
            return true;
        }

        public bool PlayerHandleDragDrop(ComponentPlayer componentPlayer, IInventory sourceInventory, int sourceSlotIndex, DragMode dragMode, IInventory targetInventory, int targetSlotIndex, bool processingOnly)
        {

            // 这里可能是处理拖拽操作的地方

            if (sourceInventory != null && targetInventory != null && sourceInventory != targetInventory)
            {
                int sourceItemID = componentPlayer.ComponentMiner.Inventory.GetSlotValue(sourceSlotIndex);
                ComponentClothing componentInventory = componentPlayer.Entity.FindComponent<ComponentClothing>();

                if (componentInventory != null)
                {
                    foreach (var data in 内存字典)
                    {
                        if (data.Key == sourceItemID && targetInventory == componentInventory)
                        {                    
                            for (int i = 0; i < data.Value.事件序号及恢复系数.GetLength(0); i++) // 获取事件序号及恢复系数 GetLength(0)获取行数 GetLength(1)获取列数
                            {
                                switch (data.Value.事件序号及恢复系数[i, 0])
                                {
                                    case 0:
                                        方法集合.事件序号0_回血(componentPlayer, data.Value.事件序号及恢复系数[i, 1]);
                                        break;
                                    case 1:
                                        方法集合.事件序号1_感冒(componentPlayer, data.Value.事件序号及恢复系数[i, 1]);
                                        break;
                                    case 2:
                                        方法集合.事件序号2_治愈感冒(componentPlayer, data.Value.事件序号及恢复系数[i, 1]);
                                        break;
                                    case 3:
                                        方法集合.事件序号3_提高摔落抗性(componentPlayer, data.Value.事件序号及恢复系数[i, 1]);
                                        break;
                                    case 4:
                                        方法集合.事件序号4_提高攻击抗性(componentPlayer, data.Value.事件序号及恢复系数[i, 1]);
                                        break;
                                    default:
                                        Log.Error("事件序号错误(0-2)");
                                        break;
                                }
                            }
                        }
                    }
                }

            }

            return true;
        }


    }

    public class 方法集合
    {
        public void 事件序号0_回血(ComponentPlayer componentPlayer, float 回血系数)
        {
            componentPlayer.ComponentHealth.Health += 回血系数;
            CommonLib.Net.QueuePackage(new ComponentHealthPackage(componentPlayer.ComponentHealth));
            DisplaySmallMessageComponentPlayer(componentPlayer, "你吃东西恢复了" + 回血系数 + "点血量。");
        }

        public void 事件序号1_感冒(ComponentPlayer componentPlayer, float 恢复Time系数)
        {
            if (恢复Time系数 > 0)
            {
                componentPlayer.ComponentFlu.m_fluDuration = 恢复Time系数;//恢复时间
                componentPlayer.ComponentFlu.m_fluOnset = 恢复Time系数;//感冒状态
                DisplaySmallMessageComponentPlayer(componentPlayer, "你吃东西感冒了，请注意饮食和休息。");
            }
            else
            {
                Log.Error("时间系数不能为负数");
            }
        }

        public void 事件序号2_治愈感冒(ComponentPlayer componentPlayer, float 恢复Time系数)
        {
            componentPlayer.ComponentFlu.m_fluDuration = 0;//恢复时间
            componentPlayer.ComponentFlu.m_fluOnset = 0;//感冒状态
            DisplaySmallMessageComponentPlayer(componentPlayer, "你吃东西治愈了感冒。");
        }

        public void 事件序号3_提高摔落抗性(ComponentPlayer componentPlayer, float 摔落抗性系数增量)
        {
            componentPlayer.ComponentHealth.FallResilience += 摔落抗性系数增量;
            CommonLib.Net.QueuePackage(new ComponentHealthPackage(componentPlayer.ComponentHealth));
            DisplaySmallMessageComponentPlayer(componentPlayer, $"你吃东西提高了{摔落抗性系数增量}摔落抗性。");
        }

        public void 事件序号4_提高攻击抗性(ComponentPlayer componentPlayer, float 提高抗性系数增量)
        {
            componentPlayer.ComponentHealth.AttackResilience += 提高抗性系数增量;
            CommonLib.Net.QueuePackage(new ComponentHealthPackage(componentPlayer.ComponentHealth));
            DisplaySmallMessageComponentPlayer(componentPlayer, $"你提高了{提高抗性系数增量}的攻击抗性");
        }

        public void DisplaySmallMessageComponentPlayer(ComponentPlayer componentPlayer, string text)  // 小消息方法 From
        {
            var messagePackget = new MessagePackage(null, text, 0, null);
            messagePackget.To = componentPlayer.PlayerData.Client;
            CommonLib.Net.QueuePackage(messagePackget);
        }

        public void DisplaySmallMessageNet广播(string text)  // 小消息方法 广播
        {
            var messagePackget = new MessagePackage("[<c=red>系统广播</c>]", text, 0, null);
            CommonLib.Net.QueuePackage(messagePackget);
        }

    }

}